package br.usp.ime.components.daos;

import java.util.List;

import javax.annotation.PostConstruct;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.jasypt.util.password.StrongPasswordEncryptor;

import br.com.caelum.vraptor.ioc.ApplicationScoped;
import br.com.caelum.vraptor.ioc.Component;
import br.usp.ime.entities.User;

@Component
@ApplicationScoped
public class UserDao {

    private final Session session;
    private StrongPasswordEncryptor passwordEncryptor = new StrongPasswordEncryptor();

    public UserDao(Session session) {
        this.session = session;
    }

    @PostConstruct
    public void createOneAdmin() {
        User user = new User();
        user.setAdministrator(true);
        user.setEmail("admin@srp.ime.usp.br");
        user.setLogin("admin");
        user.setName("Administrator");
        user.setPassword(passwordEncryptor.encryptPassword("admin"));

        if (!userExists(user))
            addUser(user);
    }

    public boolean userExists(User user) {
        return loadUser(user) != null;
    }

    public void addUser(User user) {
        if (!userExists(user)) {
            Transaction tx = this.session.beginTransaction();
            this.session.save(user);
            tx.commit();
        }
    }

    public User verifyUser(User user) {
        User verifiedUser;

        if (user == null || user.getLogin() == null
                || user.getPassword() == null)
            return null;
        verifiedUser = (User) this.session.createCriteria(User.class)
                .add(Restrictions.eq("login", user.getLogin())).uniqueResult();
        if (verifiedUser != null
                && verifiedUser.verifyPassword(user.getPassword()))
            return verifiedUser;
        return null;
    }

    public void updateUser(User user) {
        if (userExists(user)) {
            Transaction tx = this.session.beginTransaction();
            this.session.merge(user);
            tx.commit();
        }
        // session.refresh(user);
    }

    public User loadUser(User user) {
        if (user == null)
            return null;
        session.clear();
        return (User) session.createCriteria(User.class)
                .add(Restrictions.eq("login", user.getLogin())).uniqueResult();
    }

    public void deleteUser(User user) {
        User deletedUser = loadUser(user);
        if (user != null) {
            Transaction tx = this.session.beginTransaction();
            this.session.delete(deletedUser);
            tx.commit();
        }

    }

    @SuppressWarnings("unchecked")
    public List<User> listAllUsers() {
        return this.session.createCriteria(User.class).list();
    }

}
